﻿Imports System.Data.OleDb
Imports System.Text.RegularExpressions

Public Class clsVehicule

#Region "attributs"

    Private _noVehicule As Integer
    Private _noImmatriculation As String
    Private _categorie As clsCategorie
    Private _marque As String
    Private _modele As String
    Private _annee As Integer
    Private _valeur As Double
    Private _kilometrage As Integer
    Private _nbrPlaces As Integer
    Private _capaciteChargement As Integer
    Private _transmission As String
    Private _actif As Boolean
    Private _commentaire As String
    Private _options As New ArrayList

#End Region

#Region "constructeurs"

    '********************************************************************************
    ' But:  Initialiser un nouveau véhicule et, donc, lui attribuer un numéro unique
    '********************************************************************************
    Public Sub New()
        'créé un numéro de catégorie unique pour la nouvelle catégorie
        Dim bd = New cls_GestionBD("taco.mdb")
        bd.remplirDataSet("SELECT MAX(noVehicule) AS noMaximum FROM tblVehicules", "tbl")

        _noVehicule = nvl(bd.dsBd.Tables("tbl").Rows(0).Item("noMaximum"), 0) + 1
        noImmatriculation = _noVehicule
        categorie = New clsCategorie
        marque = "AucuneMarque"
        modele = "AucunModèle"
        annee = Now.Year
        valeur = 0
        kilometrage = 0
        nbrPlaces = 0
        capaciteChargement = 0
        transmission = "Automatique"
        actif = True
        commentaire = ""
        options = New ArrayList
    End Sub

    '********************************************************************************
    ' But:  Initialiser un véhicule à partir des ses informations provenant de la base de données
    ' Paramètres:
    '   row:    Enregistrement résultant d'une requête SELECT * FROM tbl
    '********************************************************************************
    Public Sub New(ByVal row As DataRow)
        With row
            _noVehicule = nvl(.Item("noVehicule"), 0)
            noImmatriculation = nvl(.Item("noImmatriculation"), "")

            Dim bdCategorie As New cls_GestionBD("taco.mdb")
            bdCategorie.daBd.SelectCommand = New OleDbCommand("SELECT * FROM tblCategories where noCategorie = @numero")
            bdCategorie.daBd.SelectCommand.Parameters.Add("@numero", OleDbType.Integer).Value = .Item("noCategorie")
            bdCategorie.remplirDataSet("tbl")

            If bdCategorie.dsBd.Tables("tbl").Rows.Count = 1 Then
                categorie = New clsCategorie(bdCategorie.dsBd.Tables("tbl").Rows(0))
            Else
                MsgBox("ERREUR: Impossible d'assigner la catégorie" & vbCrLf & _
                       "Une nouvelle catégorie sera utilisé en remplacement.")
                categorie = New clsCategorie
            End If

            marque = nvl(.Item("marque"), "AucuneMarque")
            modele = nvl(.Item("modele"), "AucunModèle")
            annee = nvl(.Item("annee"), Now.Year)
            valeur = nvl(.Item("valeur"), 0)
            kilometrage = nvl(.Item("kilometrage"), 0)
            nbrPlaces = nvl(.Item("nbrPlaces"), 0)
            capaciteChargement = nvl(.Item("capaciteChargement"), 0)
            transmission = nvl(.Item("transmission"), "Automatique")
            actif = nvl(.Item("actif"), True)
            commentaire = nvl(.Item("commentaire"), "")
            'options = nvl(, )

            Dim bdOptions As New cls_GestionBD("taco.mdb")
            bdOptions.daBd.SelectCommand = New OleDbCommand("SELECT * FROM tblOptions WHERE noOption IN( " & _
                                                            "SELECT noOption FROM tblOptionsVehicules WHERE noVehicule = @numero)")
            bdOptions.daBd.SelectCommand.Parameters.Add("@numero", OleDbType.Integer).Value = noVehicule
            bdOptions.remplirDataSet("tbl")

            options = New ArrayList

            For Each opt As DataRow In bdOptions.dsBd.Tables("tbl").Rows
                options.Add(New clsOptions(opt))
            Next



        End With
    End Sub

#End Region

#Region "get/set"

    ReadOnly Property noVehicule() As Integer
        Get
            Return _noVehicule
        End Get
    End Property

    Property noImmatriculation() As Object
        Get
            Return _noImmatriculation
        End Get
        Set(ByVal value As Object)

            Try
                ' convertit le paramètre dans le bon type
                value = CStr(value)

                ' vérifie si le paramètre respecte les spécifications
                If value <> Nothing Then
                    _noImmatriculation = value
                Else
                    Throw New Exception
                End If

            Catch ex As Exception
                MsgBox("ERREUR: Le numéro d'immatriculation est une chaine de caractères obligatoire." & vbCrLf & _
                       "Le numéro de véhicule sera utilisé en remplacement.")
                _noImmatriculation = noVehicule
            End Try

        End Set
    End Property

    Property categorie() As Object
        Get
            Return _categorie
        End Get
        Set(ByVal value As Object)

            Try

                ' convertit le paramètre dans le bon type
                value = CType(value, clsCategorie)

                _categorie = value

            Catch ex As Exception
                MsgBox("ERREUR: La catégorie doit être une instance de la classe << clsCategories >>." & vbCrLf & _
                       "Une nouvelle catégorie sera créée et utilisée en remplacement.")
                _categorie = New clsCategorie()
            End Try

        End Set
    End Property

    Property marque() As Object
        Get
            Return _marque
        End Get
        Set(ByVal value As Object)

            Try

                ' convertit le paramètre dans le bon type
                value = CStr(value)

                ' vérifie si le paramètre respecte les spécifications
                If value <> Nothing Then
                    _marque = value
                Else
                    Throw New Exception
                End If

            Catch ex As Exception
                MsgBox("ERREUR: La marque est obligatoire." & vbCrLf & _
                       "La marque << AucuneMarque >> sera utilisée en remplacement.")
                _marque = "AucuneMarque"
            End Try



        End Set
    End Property

    Property modele() As Object
        Get
            Return _modele
        End Get
        Set(ByVal value As Object)

            Try

                ' convertit le paramètre dans le bon type
                value = CStr(value)

                ' vérifie si le paramètre respecte les spécifications
                If value <> Nothing Then
                    _modele = value
                Else
                    Throw New Exception
                End If

            Catch ex As Exception
                MsgBox("ERREUR: Le modèle est obligatoire." & vbCrLf & _
                       "Le modèle << AucunModèle >> sera utilisé en remplacement.")
                _modele = "AucunModèle"
            End Try



        End Set
    End Property

    Property annee() As Object
        Get
            Return _annee
        End Get
        Set(ByVal value As Object)

            Try

                ' converti le paramètre dans le bon type
                value = CInt(value)

                ' vérifie si le paramètre respecte les spécifications
                If value >= Now.Year - 20 AndAlso value <= Now.Year Then
                    _annee = value
                Else
                    Throw New Exception
                End If

            Catch ex As Exception
                MsgBox("ERREUR: L'année doit être entre " & Now.Year - 20 & " et " & Now.Year & "." & vbCrLf & _
                       "L'anné << " & Now.Year & " >> sera utilisé en remplacement.")
                _annee = Now.Year
            End Try

        End Set
    End Property

    Property valeur() As Object
        Get
            Return _valeur
        End Get
        Set(ByVal value As Object)

            Try

                ' convertit le paramètre dans le bon type
                value = CInt(value)

                ' vérifie si le paramètre respecte les spécifications
                If value >= 0 Then
                    _valeur = value
                Else
                    Throw New Exception
                End If

            Catch ex As Exception
                MsgBox("ERREUR: La valeur doit être un nombre plus grand ou égale à zéro." & vbCrLf & _
                       "La valeur << 0 >> sera utilisé en remplacement.")
                _valeur = 0
            End Try

        End Set
    End Property

    Property kilometrage() As Object
        Get
            Return _kilometrage
        End Get
        Set(ByVal value As Object)

            Try
                ' convertit le paramètre dans le bon type
                value = CInt(value)

                ' vérifie si le paramètre respecte les spécifications
                If value >= 0 Then
                    _kilometrage = value
                Else
                    Throw New Exception
                End If

            Catch ex As Exception
                MsgBox("ERREUR: Le kilométrage doit être un nombre entier plus grand ou égale à zéro." & vbCrLf & _
                       "La valeur << 0 >> sera utilisé en remplacement.")
                _kilometrage = 0
            End Try

        End Set
    End Property

    Property nbrPlaces() As Object
        Get
            Return _nbrPlaces
        End Get
        Set(ByVal value As Object)

            Try
                ' convertit le paramètre dans le bon type
                value = CInt(value)

                ' vérifie si le paramètre respecte les spécifications
                If value >= 0 Then
                    _nbrPlaces = value
                Else
                    Throw New Exception
                End If

            Catch ex As Exception
                MsgBox("ERREUR: Le nombre de places doit être un nombre entier plus grand ou égale à zéro." & vbCrLf & _
                       "La valeur << 0 >> sera utilisé en remplacement")
                _nbrPlaces = 0
            End Try

        End Set
    End Property

    Property capaciteChargement() As Object
        Get
            Return _capaciteChargement
        End Get
        Set(ByVal value As Object)

            Try
                ' convertit le paramètre dans le bon type
                value = CInt(value)

                ' vérifie si le paramètre respecte les spécifications
                If value >= 0 Then
                    _capaciteChargement = value
                Else
                    Throw New Exception
                End If

            Catch ex As Exception
                MsgBox("ERREUR: La capacité de chargement doit être un nombre entier plus grand ou égale à zéro." & vbCrLf & _
                       "La valeur << 0 >> sera utilisé en remplacement.")
                _capaciteChargement = 0
            End Try

        End Set
    End Property

    Property transmission() As Object
        Get
            Return _transmission
        End Get
        Set(ByVal value As Object)

            Try

                ' convertit le paramètre dans le bon type
                value = CStr(value)

                Dim regTransmission As New Regex("^(Automatique|Manuelle)$")

                'vérifie si le paramètre respecte les spécifications
                If regTransmission.IsMatch(value) Then
                    _transmission = value
                Else
                    Throw New Exception
                End If

            Catch ex As Exception
                MsgBox("ERREUR: La transmission doit être soit << Automatique >>, soit << Manuelle >>." & vbCrLf & _
                       "La valeur << Automatique >> sera utilisé en remplacement.")
                _transmission = "Automatique"
            End Try



        End Set
    End Property

    Property actif() As Object
        Get
            Return _actif
        End Get
        Set(ByVal value As Object)

            Try
                ' convertit le paramètre dans le bon type
                value = CBool(value)

                _actif = value

            Catch ex As Exception
                MsgBox("ERREUR: La valeur de actif peut être soit << True >> ou << False >>." & vbCrLf & _
                       "La valeur de actif << True >> sera utilisé en remplacement.")
                _actif = ""
            End Try

        End Set
    End Property

    Property commentaire() As Object
        Get
            Return _commentaire
        End Get
        Set(ByVal value As Object)

            Try
                ' convertit le paramètre dans le bon type
                value = CStr(value)

                _commentaire = value

            Catch ex As Exception
                MsgBox("ERREUR: Le commentaire doit être une chaine de caractères." & vbCrLf & _
                       "Le commentaire << >> sera utilisé en remplacement.")
                _commentaire = ""
            End Try

        End Set
    End Property

    Property options() As Object
        Get
            Return _options
        End Get
        Set(ByVal value As Object)

            Try

                ' convertit le paramètre dans le bon type
                value = CType(value, ArrayList)

                'parcours chaque objet de l'arrayList et note si tout les objets sont des options
                Dim objetsMauvaisType As Boolean = False

                For Each element In value
                    If Not (TypeOf element Is clsOptions) Then
                        objetsMauvaisType = True
                        Exit For
                    End If
                Next

                'si un ou plusieurs objets ne sont pas des options l'arrayList est ignoré
                If objetsMauvaisType Then
                    MsgBox("ERREUR: Certains objets de l'arrayList ne sont pas des options." & vbCrLf & _
                           "L'arrayList sera ignoré.")
                    _options = New ArrayList()
                Else
                    _options = value
                End If

            Catch ex As Exception
                MsgBox("ERREUR: L'attribut << options >> doit contenir un arrayList.")
                _options = New ArrayList()
            End Try





        End Set
    End Property

#End Region

#Region "méthodes"

    '********************************************************************************
    ' But:  Enregistrer le véhicule, sa catégorie et toutes ses options dans la base de données
    '********************************************************************************
    Public Sub enregistrer()
        'importe le véhicule de la base de données
        Dim bd As New cls_GestionBD("taco.mdb")
        bd.daBd.SelectCommand = New OleDbCommand("SELECT * FROM tblVehicules where noVehicule = @numero")
        bd.daBd.SelectCommand.Parameters.Add("@numero", OleDbType.Integer).Value = noVehicule
        bd.remplirDataSet("tbl")

        'met à jour le véhicule si il existe déjà dans la base de données
        If bd.dsBd.Tables("tbl").Rows.Count = 1 Then
            With bd.dsBd.Tables("tbl").Rows(0)
                .Item("noVehicule") = noVehicule
                .Item("noImmatriculation") = noImmatriculation
                categorie.enregistrer()     'enregistre la catégorie pour ne pas avoir une erreur de clé étrangère
                .Item("noCategorie") = categorie.noCategorie
                .Item("marque") = marque
                .Item("modele") = modele
                .Item("annee") = annee
                .Item("valeur") = valeur
                .Item("kilometrage") = kilometrage
                .Item("nbrPlaces") = nbrPlaces
                .Item("capaciteChargement") = capaciteChargement
                .Item("transmission") = transmission
                .Item("actif") = actif
                .Item("commentaire") = commentaire
            End With

            'créé un nouvel enregistrement si le véhicule n'existe pas encore dans la base de données
        ElseIf bd.dsBd.Tables("tbl").Rows.Count = 0 Then

            Dim lNewRow As DataRow
            lNewRow = bd.dsBd.Tables("tbl").NewRow

            With lNewRow
                .Item("noVehicule") = noVehicule
                .Item("noImmatriculation") = noImmatriculation
                categorie.enregistrer()
                .Item("noCategorie") = categorie.noCategorie
                .Item("marque") = marque
                .Item("modele") = modele
                .Item("annee") = annee
                .Item("valeur") = valeur
                .Item("kilometrage") = kilometrage
                .Item("nbrPlaces") = nbrPlaces
                .Item("capaciteChargement") = capaciteChargement
                .Item("transmission") = transmission
                .Item("actif") = actif
                .Item("commentaire") = commentaire
            End With

            bd.dsBd.Tables("tbl").Rows.Add(lNewRow)

        End If

        'met à jour la base de données
        bd.miseAJourBD("tbl")

        'ajoute les liens entre le véhicule et ses options
        bd = New cls_GestionBD("taco.mdb")
        bd.daBd.SelectCommand = New OleDbCommand("SELECT * FROM tblOptionsVehicules WHERE noVehicule = @numero")
        bd.daBd.SelectCommand.Parameters.Add("@numero", OleDbType.Integer).Value = noVehicule
        bd.remplirDataSet("tbl")

        For Each row As DataRow In bd.dsBd.Tables("tbl").Rows
            row.Delete()
        Next

        For Each opt As clsOptions In options
            opt.enregistrer()   'enregistre l'option pour ne pas avoir une erreur de clé étrangère

            Dim lNewRow As DataRow
            lNewRow = bd.dsBd.Tables("tbl").NewRow

            With lNewRow
                .Item("noVehicule") = noVehicule
                .Item("noOption") = opt.numero
                bd.dsBd.Tables("tbl").Rows.Add(lNewRow)
            End With

            bd.miseAJourBD("tbl")

        Next
    End Sub

    '********************************************************************************
    ' But:  Supprimer le véhicule de la base de données
    '********************************************************************************
    Public Sub supprimer()
        'importe le véhicule de la base de données
        Dim bd As New cls_GestionBD("taco.mdb")
        bd.daBd.SelectCommand = New OleDbCommand("SELECT * FROM tblVehicules where noVehicule = @numero")
        bd.daBd.SelectCommand.Parameters.Add("@numero", OleDbType.Integer).Value = noVehicule
        bd.remplirDataSet("tbl")

        'supprime le véhicule si elle existe dans la base de données, sinon, affiche un message d'erreur
        If bd.dsBd.Tables("tbl").Rows.Count = 1 Then
            bd.dsBd.Tables("tbl").Rows(0).Delete()
        ElseIf bd.dsBd.Tables("tbl").Rows.Count = 0 Then
            MsgBox("ERREUR: Le véhicule n'existe pas dans la base de données." & vbCrLf & _
                   "Il est donc impossible de la supprimer.")
        End If

        'met à jour la base de données
        bd.miseAJourBD("tbl")

    End Sub

    '********************************************************************************
    ' But:  Afficher tous les attributs du véhicule, de sa catégorie et de ses options
    ' Return:   Une chaine de caractère contenant chaque attribut accompagné de sa valeur
    '********************************************************************************
    Public Overrides Function ToString() As String
        Dim reponse As String = "noVehicule:" & vbTab & noVehicule & vbCrLf & _
                "noImmatriculation:" & vbTab & noImmatriculation & vbCrLf & _
                "categorie:" & vbCrLf & categorie.ToString & vbCrLf & _
                "marque:" & vbTab & marque & vbCrLf & _
                "modele:" & vbTab & modele & vbCrLf & _
                "annee:" & vbTab & annee & vbCrLf & _
                "valeur:" & vbTab & valeur & vbCrLf & _
                "kilometrage:" & vbTab & kilometrage & vbCrLf & _
                "nbrPlaces:" & vbTab & nbrPlaces & vbCrLf & _
                "capaciteChargement:" & vbTab & capaciteChargement & vbCrLf & _
                "transmission:" & vbTab & transmission & vbCrLf & _
                "actif:" & vbTab & actif & vbCrLf & _
                "commentaire:" & vbTab & commentaire & vbCrLf & _
                "options:" & vbCrLf

        For Each opt As clsOptions In options
            reponse &= opt.ToString()
        Next

        Return reponse
    End Function

#End Region

End Class